package com.cleaningcloud.cld.service.impl;

import com.cleaningcloud.cld.domain.CldCalendar;
import com.cleaningcloud.cld.domain.CldPayConfirm;
import com.cleaningcloud.cld.domain.CldPayDetails;
import com.cleaningcloud.cld.domain.CldProject;
import com.cleaningcloud.cld.domain.dto.CldPayConfirmDto;
import com.cleaningcloud.cld.domain.dto.CldPayConfirmVo;
import com.cleaningcloud.cld.domain.dto.CldPayDetailsDto;
import com.cleaningcloud.cld.domain.dto.CldProjectPostDto;
import com.cleaningcloud.cld.domain.model.TableCalendarVo;
import com.cleaningcloud.cld.domain.vo.CldProjectPostSetVo;
import com.cleaningcloud.cld.mapper.CldPayConfirmMapper;
import com.cleaningcloud.cld.mapper.CldPayDetailsMapper;
import com.cleaningcloud.cld.mapper.CldProjectMapper;
import com.cleaningcloud.cld.mapper.CldProjectPostMapper;
import com.cleaningcloud.cld.service.ICldCalendarService;
import com.cleaningcloud.cld.service.ICldPayDetailsService;
import com.cleaningcloud.common.core.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;

/**
 * 薪酬管理Service业务层处理
 *
 * @author cleaningcloud
 * @date 2024-11-08
 */
@Service
public class CldPayDetailsServiceImpl implements ICldPayDetailsService {
    @Autowired
    private CldPayDetailsMapper cldPayDetailsMapper;

    @Autowired
    private CldPayConfirmMapper cldPayConfirmMapper;

    @Autowired
    private CldProjectMapper cldProjectMapper;

    @Autowired
    private CldProjectPostMapper cldProjectPostMapper;

    @Autowired
    private ICldCalendarService calendarService;


    /**
     * 查询薪酬管理
     *
     * @param payDetailsId 薪酬管理主键
     * @return 薪酬管理
     */
    @Override
    public CldPayDetails selectCldPayDetailsByPayDetailsId(Long payDetailsId) {
        return cldPayDetailsMapper.selectCldPayDetailsByPayDetailsId(payDetailsId);
    }

    /**
     * 查询薪酬管理列表
     *
     * @param cldPayDetails 薪酬管理
     * @return 薪酬管理
     */
    @Override
    public List<CldPayDetails> selectCldPayDetailsList(CldPayDetails cldPayDetails) {
        return cldPayDetailsMapper.selectCldPayDetailsList(cldPayDetails);
    }

    /**
     * 新增薪酬管理
     *
     * @param cldPayDetails 薪酬管理
     * @return 结果
     */
    @Override
    @Transactional
    public int insertCldPayDetails(CldPayDetails cldPayDetails) {
        LocalDate localDate = LocalDate.now();
        cldPayDetails.setYear(cldPayDetails.getYear() == null ? localDate.getYear() : cldPayDetails.getYear());
        cldPayDetails.setMonth(cldPayDetails.getMonth() == null ? localDate.getMonthValue() : cldPayDetails.getMonth());
        cldPayDetails.setDay(cldPayDetails.getDay() == null ? localDate.getDayOfMonth() : cldPayDetails.getDay());
        cldPayDetails.setProduceTime(DateUtils.getNowDate());
        cldPayDetailsMapper.insertCldPayDetails(cldPayDetails);
        // 同步修改薪酬确认表数据
        editPayConfirm(cldPayDetails);
        return 1;
    }

    /**
     * 修改薪酬管理
     *
     * @param cldPayDetails 薪酬管理
     * @return 结果
     */
    @Override
    @Transactional
    public int updateCldPayDetails(CldPayDetails cldPayDetails) {
        // 查询修改前
        updatePayDetails(cldPayDetails);
        return 1;
    }

    private void updatePayDetails(CldPayDetails cldPayDetails) {
        CldPayDetails payDetails = cldPayDetailsMapper.selectCldPayDetailsByPayDetailsId(cldPayDetails.getPayDetailsId());
        cldPayDetailsMapper.updateCldPayDetails(cldPayDetails);
        editPayConfirm(payDetails);
    }

    @Override
    @Transactional
    public int batchUpdateCldPayDetails(List<CldPayDetails> list) {
        for (CldPayDetails cldPayDetails : list) {
            // 查询修改前
            updatePayDetails(cldPayDetails);
        }
        return 1;
    }

    private void editPayConfirm(CldPayDetails cldPayDetails) {
        // 查询当天薪酬明细记录 累计薪酬总额
        CldPayDetails payDetailsQuery = new CldPayDetails();
        payDetailsQuery.setProjectId(cldPayDetails.getProjectId());
        payDetailsQuery.setYear(cldPayDetails.getYear());
        payDetailsQuery.setMonth(cldPayDetails.getMonth());
        payDetailsQuery.setDay(cldPayDetails.getDay());
        payDetailsQuery.setStaffId(cldPayDetails.getStaffId());
        List<CldPayDetails> cldPayDetailsList = cldPayDetailsMapper.selectCldPayDetailsList(payDetailsQuery);
        // 薪酬确认总值
        BigDecimal sumPay = new BigDecimal("0.0");
        for (CldPayDetails payDetails : cldPayDetailsList) {
            sumPay = sumPay.add(payDetails.getMoney());
        }
        CldPayConfirm payConfirmQuery = new CldPayConfirm();
        payConfirmQuery.setYear(cldPayDetails.getYear());
        payConfirmQuery.setMonth(cldPayDetails.getMonth());
        payConfirmQuery.setDay(cldPayDetails.getDay());
        payConfirmQuery.setStaffId(cldPayDetails.getStaffId());
        payConfirmQuery.setProjectId(cldPayDetails.getProjectId());
        List<CldPayConfirm> payConfirmList = cldPayConfirmMapper.selectCldPayConfirmList(payConfirmQuery);
        if (payConfirmList.isEmpty()) {
            // 为空则新增
            CldPayConfirm cldPayConfirm = new CldPayConfirm();
            cldPayConfirm.setYear(cldPayDetails.getYear());
            cldPayConfirm.setMonth(cldPayDetails.getMonth());
            cldPayConfirm.setDay(cldPayDetails.getDay());
            cldPayConfirm.setSumPay(sumPay);
            cldPayConfirm.setIsConfirm(0L);
            cldPayConfirm.setProjectId(cldPayDetails.getProjectId());
            cldPayConfirm.setStaffId(cldPayDetails.getStaffId());
            cldPayConfirm.setIsSend(0L);
            cldPayConfirm.setCreateTime(DateUtils.getNowDate());
            cldPayConfirmMapper.insertCldPayConfirm(cldPayConfirm);
        } else {
            CldPayConfirm cldPayConfirm = payConfirmList.get(0);
            cldPayConfirm.setSumPay(sumPay);
            cldPayConfirmMapper.updateCldPayConfirm(cldPayConfirm);
        }
    }

    /**
     * 批量删除薪酬管理
     *
     * @param payDetailsIds 需要删除的薪酬管理主键
     * @return 结果
     */
    @Override
    public int deleteCldPayDetailsByPayDetailsIds(Long[] payDetailsIds) {
        return cldPayDetailsMapper.deleteCldPayDetailsByPayDetailsIds(payDetailsIds);
    }

    /**
     * 删除薪酬管理信息
     *
     * @param payDetailsId 薪酬管理主键
     * @return 结果
     */
    @Override
    public int deleteCldPayDetailsByPayDetailsId(Long payDetailsId) {
        return cldPayDetailsMapper.deleteCldPayDetailsByPayDetailsId(payDetailsId);
    }

    @Override
    public CldPayDetails selectCldPayDetailsByBusinessId(Long businessId) {
        return cldPayDetailsMapper.selectCldPayDetailsByBusinessId(businessId);
    }

    @Override
    public List<Map<String, Object>> selectRealTimeSalaryGrouping(CldPayDetailsDto cldPayDetailsDto) {
        return cldPayDetailsMapper.selectRealTimeSalaryGrouping(cldPayDetailsDto);
    }

    @Override
    public List<Map<String, Object>> getCumulativeSalaryList(CldPayDetailsDto cldPayDetailsDto) {
        return cldPayDetailsMapper.getCumulativeSalaryList(cldPayDetailsDto);
    }

    @Override
    public List<Map<String, Object>> getCumulativeSalaryByProjectId(CldPayConfirm cldPayConfirm) {
        return cldPayDetailsMapper.getCumulativeSalaryByProjectId(cldPayConfirm);
    }

    @Override
    public List<Map<String, Object>> selectSalaryStatistics(CldPayDetailsDto cldPayDetailsDto) {
        return cldPayDetailsMapper.selectSalaryStatistics(cldPayDetailsDto);
    }

    @Override
    public Map<String, Object> getTableCalendarList(CldPayDetailsDto cldPayDetailsDto) {
        // 查询项目信息
        CldProject cldProject = cldProjectMapper.selectCldProjectByProjectId(cldPayDetailsDto.getProjectId());
        if (cldProject == null) {
            throw new RuntimeException("查询项目信息失败！");
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("projectName", cldProject.getProjectName());
        resultMap.put("projectStatus", cldProject.getProjectStatus());
        // 查询当月日历信息
        CldCalendar calendarQuery = new CldCalendar();
        calendarQuery.setCalendarYear(Math.toIntExact(cldPayDetailsDto.getYear()));
        calendarQuery.setCalendayMonth(Math.toIntExact(cldPayDetailsDto.getMonth()));
        List<CldCalendar> calendarList = calendarService.selectCldCalendarList(calendarQuery);
        resultMap.put("calendarList", calendarList);
        List<TableCalendarVo> tableCalendarVoList = new ArrayList<>();
        if(cldProject.getProjectStatus() == 2) {
            // 查询项目所有人员信息
            CldPayDetails queryDetails = new CldPayDetails();
            queryDetails.setProjectId(cldProject.getProjectId());
            queryDetails.setYear(cldPayDetailsDto.getYear());
            queryDetails.setMonth(cldPayDetailsDto.getMonth());
            List<CldPayDetails> detailsList = cldPayDetailsMapper.getCldPayDetailsList(queryDetails);
            for (CldPayDetails details : detailsList) {
                if (details.getStaffId() != null) {
                    TableCalendarVo tableCalendarVo = new TableCalendarVo();
                    tableCalendarVo.setStaffName(details.getStaffName());
                    tableCalendarVo.setStaffStatus(details.getStaffStatus());
                    tableCalendarVo.setProjectPostName(details.getProjectPostName());
                    tableCalendarVo.setProjectPostNo(details.getProjectPostNo());
                    tableCalendarVo.setProjectDuitsName(details.getProjectDuitsName());
                    tableCalendarVo.setPostWages(details.getPostWages() == null ? new BigDecimal(1900) : details.getPostWages());
                    if (details.getGroupName() != null) {
                        tableCalendarVo.setGroupName(details.getGroupName().toString());
                    }
                    tableCalendarVo.setStaffId(details.getStaffId());
                    // 根据项目岗位人员查询薪酬记录
                    CldPayConfirmDto payConfirmQuery = new CldPayConfirmDto();
                    payConfirmQuery.setProjectId(cldProject.getProjectId());
                    payConfirmQuery.setYear(cldPayDetailsDto.getYear());
                    payConfirmQuery.setMonth(cldPayDetailsDto.getMonth());
                    payConfirmQuery.setStaffId(details.getStaffId());
                    if(null != details.getProjectPostName()){
                        payConfirmQuery.setProjectPostName(details.getProjectPostName());
                    }
                    Map<String, Object> payConfirmMap = new HashMap<>();
                    List<CldPayConfirmVo> payConfirmVoList = cldPayConfirmMapper.getTableCalendarList(payConfirmQuery);
                    for (CldPayConfirmVo payConfirmVo : payConfirmVoList) {
                        payConfirmMap.put(payConfirmVo.getYear() + "-" + (payConfirmVo.getMonth() < 10 ? "0" + payConfirmVo.getMonth() : payConfirmVo.getMonth()) + "-" + (payConfirmVo.getDay() < 10 ? "0" + payConfirmVo.getDay() : payConfirmVo.getDay()), payConfirmVo);
                    }
                    tableCalendarVo.setDayData(payConfirmMap);
                    tableCalendarVoList.add(tableCalendarVo);
                }
            }
        }else{
            CldPayConfirmDto payConfirmQuery = new CldPayConfirmDto();
            payConfirmQuery.setProjectId(cldProject.getProjectId());
            payConfirmQuery.setYear(cldPayDetailsDto.getYear());
            payConfirmQuery.setMonth(cldPayDetailsDto.getMonth());
            List<CldPayConfirmVo> payConfirmVoList = cldPayConfirmMapper.getTerminationTableCalendarList(payConfirmQuery);
            for (CldPayConfirmVo cldPayConfirmVo : payConfirmVoList) {
                if(tableCalendarVoList.stream().noneMatch(n -> n.getStaffId().equals(cldPayConfirmVo.getStaffId()))) {
                    TableCalendarVo tableCalendarVo = new TableCalendarVo();
                    tableCalendarVo.setStaffName(cldPayConfirmVo.getStaffName());
                    tableCalendarVo.setStaffId(cldPayConfirmVo.getStaffId());
                    tableCalendarVoList.add(tableCalendarVo);
                }
            }
            for (TableCalendarVo tableCalendarVo : tableCalendarVoList) {
                // 根据项目岗位人员查询薪酬记录
                payConfirmQuery = new CldPayConfirmDto();
                payConfirmQuery.setProjectId(cldProject.getProjectId());
                payConfirmQuery.setYear(cldPayDetailsDto.getYear());
                payConfirmQuery.setMonth(cldPayDetailsDto.getMonth());
                payConfirmQuery.setStaffId(tableCalendarVo.getStaffId());
                Map<String, Object> payConfirmMap = new HashMap<>();
                payConfirmVoList = cldPayConfirmMapper.getTerminationTableCalendarList(payConfirmQuery);
                for (CldPayConfirmVo payConfirmVo : payConfirmVoList) {
                    payConfirmMap.put(payConfirmVo.getYear() + "-" + (payConfirmVo.getMonth() < 10 ? "0" + payConfirmVo.getMonth() : payConfirmVo.getMonth()) + "-" + (payConfirmVo.getDay() < 10 ? "0" + payConfirmVo.getDay() : payConfirmVo.getDay()), payConfirmVo);
                }
                tableCalendarVo.setDayData(payConfirmMap);
            }
        }
        resultMap.put("staffList", tableCalendarVoList);
        return resultMap;
    }

    @Override
    public Map<String, Object> getCalendarByStaffId(CldPayDetailsDto cldPayDetailsDto) {
        Map<String, Object> resultMap = new HashMap<>();
        // 根据项目岗位人员查询薪酬记录
        CldPayConfirmDto payConfirmQuery = new CldPayConfirmDto();
        payConfirmQuery.setProjectId(cldPayDetailsDto.getProjectId());
        payConfirmQuery.setYear(cldPayDetailsDto.getYear());
        payConfirmQuery.setMonth(cldPayDetailsDto.getMonth());
        payConfirmQuery.setStaffId(cldPayDetailsDto.getStaffId());
        List<CldPayConfirmVo> payConfirmVoList = cldPayConfirmMapper.getTableCalendarList(payConfirmQuery);
        for (CldPayConfirmVo payConfirmVo : payConfirmVoList) {
            resultMap.put(payConfirmVo.getYear() + "-" + (payConfirmVo.getMonth() < 10 ? "0" + payConfirmVo.getMonth() : payConfirmVo.getMonth()) + "-" + (payConfirmVo.getDay() < 10 ? "0" + payConfirmVo.getDay() : payConfirmVo.getDay()), payConfirmVo);
        }
        return resultMap;
    }

    @Override
    public Map<String, Object> salaryHeadStatistics() {
        return cldPayDetailsMapper.salaryHeadStatistics();
    }
}
